﻿using System.Linq;
using Abp.Domain.Uow;
using Hicap.AuthorizationServer.Core;
using Hicap.AuthorizationServer.Core.Common;
using Hicap.AuthorizationServer.Core.Models.Sys;
using Microsoft.EntityFrameworkCore;

namespace Hicap.AuthorizationServer.EntityFrameworkCore.Seed.Host
{
    public class HostRoleAndUserCreator
    {
        private readonly AuthorizationServerDbContext _context;
        private readonly IUnitOfWorkManager _unitOfWorkManager;

        public HostRoleAndUserCreator(AuthorizationServerDbContext context, IUnitOfWorkManager unitOfWorkManager)
        {
            _context = context;
            _unitOfWorkManager = unitOfWorkManager;
        }

        [UnitOfWork]
        public Role Create()
        {
            var user = CreateAdminUser();
            var role = CreateAdminRole();
            CreateAdminUserRoleRelated(user, role);
            return role;
        }

        [UnitOfWork]
        private void CreateAdminUserRoleRelated(User user, Role role)
        {
            var adminUserRoleRelated = _context.UserRoleRelated.IgnoreQueryFilters().Any(r => r.Role.RoleCode == AuthorizationServerConsts.AdminRoleCode && r.User.UserCode == AuthorizationServerConsts.AdminUserCode);

            if (!adminUserRoleRelated)
            {
                _context.UserRoleRelated.Add(new UserRoleRelated
                {
                    User = user,
                    Role = role,
                });
                _context.SaveChanges();
            }
        }

        [UnitOfWork]
        private Role CreateAdminRole()
        {
            var role = new Role()
            {
                RoleCode = AuthorizationServerConsts.AdminRoleCode,
                RoleName = AuthorizationServerConsts.AdminRoleName,
            };

            var adminRoleForHost = _context.Role.IgnoreQueryFilters().FirstOrDefault(r => r.RoleCode == AuthorizationServerConsts.AdminRoleCode);
            if (adminRoleForHost == null)
            {
                _context.Role.Add(role);
                _context.SaveChanges();
            }

            return role;
        }

        [UnitOfWork]
        private User CreateAdminUser()
        {
            var entity = new User()
            {
                UserCode = AuthorizationServerConsts.AdminUserCode,
                UserName = AuthorizationServerConsts.AdminUserName,
                UserRealName = AuthorizationServerConsts.AdminUserName,
                UserRemarks = "初始用户，仅用于创建用户，分配默认权限。",
                CurPassword = Encrypt.HmacSHA256(AuthorizationServerConsts.DefaultPassword, AuthorizationServerConsts.DefaultPassPhrase)
            };

            var adminUserForHost = _context.User.IgnoreQueryFilters().Any(r => r.UserCode == AuthorizationServerConsts.AdminUserCode);

            if (!adminUserForHost)
            {
                _context.User.Add(entity);
                _context.SaveChanges();
            }

            return entity;
        }
    }
}